package com.eksframework.commons.core.check;

import com.eksframework.commons.core.constant.ConstRegex;

/**
 * 身份证校验
 *
 * @author: chenfenghai
 * @version: 1.0
 * @date: 2021-04-28 15:11
 */
public class IDCheck {

    /**
     * 18位身份证长度
     */
    public static final int ID_NO_LENGTH_18 = 18;

    /**
     * 15位身份证长度
     */
    public static final int ID_NO_LENGTH_15 = 15;

    /**
     * 构造函数
     */
    IDCheck() {
    }

    /**
     * 是否15位身份证号
     *
     * @param id 身份证字符串
     * @return boolean
     */
    public static boolean isID15(String id) {
        if (id == null || id.length() != ID_NO_LENGTH_15) {
            return false;
        }
        return id.matches(ConstRegex.ID_NO_15);
    }

    /**
     * 不是15位身份证号
     *
     * @param id 身份证字符串
     * @return boolean
     */
    public static boolean notID15(String id) {
        return !isID15(id);
    }

    /**
     * 是否18位身份证号
     *
     * @param id 身份证字符串
     * @return boolean
     */
    public static boolean isID18(String id) {
        if (!matchRegex18(id)) {
            return false;
        }
        String lastBit = computeLastBit(id);
        return lastBit.equalsIgnoreCase(id.substring(ID_NO_LENGTH_18 - 1));
    }

    /**
     * 不是18位身份证号
     *
     * @param id 身份证字符串
     * @return boolean
     */
    public static boolean notID18(String id) {
        return !isID18(id);
    }

    /**
     * 是否身份证号
     *
     * @param id 身份证字符串
     * @return boolean
     */
    public static boolean isID(String id) {
        return isID18(id) || isID15(id);
    }

    /**
     * 不是身份证号
     *
     * @param id 身份证字符串
     * @return boolean
     */
    public static boolean notID(String id) {
        return !isID(id);
    }

    /**
     * 是否匹配18位正则表达式
     *
     * @param id 身份证字符串
     * @return boolean
     */
    private static boolean matchRegex18(String id) {
        if (id == null || id.length() != ID_NO_LENGTH_18) {
            return false;
        }
        return id.matches(ConstRegex.ID_NO_18);
    }

    /**
     * 计算最后一位校验值
     *
     * @param id 身份证字符串
     * @return 身份证第18位字符
     */
    public static String computeLastBit(String id) {
        if (notID15(id) && !matchRegex18(id)) {
            return "";
        }
        String id18 = id.length() == ID_NO_LENGTH_18 ? id : id.substring(0, 6) + "19" + id.substring(6);
        int[] factor = new int[]{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
        char[] id18Array = id18.toCharArray();
        int sum = 0;
        for (int i = 0; i < factor.length; ++i) {
            sum += Integer.parseInt(String.valueOf(id18Array[i])) * factor[i];
        }
        String[] checkArray = new String[]{"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
        return checkArray[sum % 11];
    }
}
